#include "BondDetailPage.h"

#include <core/StyleMgr.h>
#include <qbtools/tools.h>
#include <uam/UserAccountManager.h>
#include <widgets/table/STable.h>
#include <widgets/table/STableColumnSet.h>

#include <QDebug>
#include <QHeaderView>
#include <QTableView>

#include "../BondColDelegate.h"
#include "BondDetailData.h"
#include "ui_BondDetailPage.h"

const int kRowHeight = 24;

BondDetailPage::BondDetailPage(QWidget* parent)
    : QWidget(parent), ui(new Ui::BondDetailPage) {
  ui->setupUi(this);

  const QColor& normal = StyleMgr::instance().color("ButtonDisable");
  const QColor& hover = StyleMgr::instance().color("Hover");
  const QColor& checked_bkg = StyleMgr::instance().color("BackNormal");
  const QColor& checked = StyleMgr::instance().color("TabSelBorder");
  const QColor& text = StyleMgr::instance().color("ChartH8");
  const auto& buttons = ui->buttonGroup_quote->buttons();
  for (auto button : buttons) {
    button->setStyleSheet(QString("QPushButton {"
                                  "  background-color: #%1;"
                                  "}"
                                  "QPushButton:hover {"
                                  "  background-color: #%2;"
                                  "}"
                                  "QPushButton:checked {"
                                  "  border: 1px solid #%3;"
                                  "  color: #%3;"
                                  "  background-color: #%4;"
                                  "}")
                              .arg(normal.rgb(), 0, 16)
                              .arg(hover.rgb(), 0, 16)
                              .arg(checked.rgb(), 0, 16)
                              .arg(checked_bkg.rgb(), 0, 16));
  }

  QPushButton* tab_buttons[] = {ui->AllMarket, ui->Broker, ui->CFETS,
                                ui->Exchange, ui->SHFixed};
  for (int i = 0; i < sizeof(tab_buttons) / sizeof(tab_buttons[0]); ++i) {
    ui->buttonGroup_quote->setId(tab_buttons[i], i);
  }

  setStyleSheet(QString(".QFrame { background-color: #%1; border-radius: 2px;}"
                        "QLabel#BasicI { "
                        "  margin: 1px;"
                        "  border: 1px solid #%2;"
                        "  border-radius: 7px;"
                        "}")
                    .arg(normal.rgb(), 0, 16)
                    .arg(text.rgb(), 0, 16));

  connect(ui->buttonGroup_quote, &QButtonGroup::idToggled, this,
          &BondDetailPage::onCurrentTabChanged);
  ui->btnShowDeals->setVisible(ui->Exchange->isChecked());
}

BondDetailPage::~BondDetailPage() {
  m_data->reqExchangeData(false);
  delete ui;
}

static std::vector<bool> getMarketsForBond(QSharedPointer<DetailData> data) {
  std::vector<bool> vctPage(8, 0);
  const auto& bondInfo = data->bond();
  qDebug() << "MarketType" << bondInfo.GetMarketType();
  qDebug() << "ListedMarket" << bondInfo.GetListedMarket();
  if (atoi(bondInfo.GetMarketType()) == 2) {
    if (1)  // m_showAllMarketTab
      vctPage[(int)BondDetailAllMarket::AllMarket] = 1;
    vctPage[(int)BondDetailAllMarket::Broker] = 1;
    if (strcmp(bondInfo.GetListedMarket(), CBondContainer::lmCIB) == 0) {
      if (1)  // m_bCFETSRights
        vctPage[(int)BondDetailAllMarket::CFETS] = 1;
    } else {
      if (SSUserAccountManager::instance().HasExchangeAuth(
              bondInfo.GetListedMarket())) {
        vctPage[(int)BondDetailAllMarket::Exchange] = 1;
        if (strcmp(bondInfo.GetListedMarket(), CBondContainer::lmSSE) == 0) {
          vctPage[(int)BondDetailAllMarket::SHFixed] = 1;
        }
      }
    }
  } else {
    vctPage[(int)BondDetailAllMarket::AllMarket] = 1;
    vctPage[(int)BondDetailAllMarket::Broker] = 1;
    // vctPage[(int)BondDetailAllMarket::CFETS] = 1;
    // vctPage[(int)BondDetailAllMarket::Exchange] = 1;
    // vctPage[(int)BondDetailAllMarket::SHFixed] = 1;
  }
  return vctPage;
}

void BondDetailPage::setDetailData(QSharedPointer<DetailData> data) {
  ui->Title->setDetailData(data);
  ui->Chart->setDetailData(data);
  ui->QuoteAndStream->setDetailData(data);
  ui->PriceInterMarket->setDetailData(data);

  const std::vector<bool> markets = getMarketsForBond(data);
  const auto& buttons = ui->buttonGroup_quote->buttons();
  for (auto button : buttons) {
    button->setVisible(markets[ui->buttonGroup_quote->id(button)]);
  }

  ui->QuoteAndStream->setQuoteType(BondDetailAllMarket::AllMarket, markets);
  m_data = data;

  initBest5BOinExchange();

  if (markets[(int)BondDetailAllMarket::Exchange]) {
    connect(m_data.get(), &DetailData::ExchangeDataChanged, this,
            &BondDetailPage::onExchangeDataChanged);
    m_data->reqExchangeData(true);
  }
}

void BondDetailPage::initBest5BOinExchange() {
  const int max_col_count = 4;
  const QVector<int> seqNoLst = {5, 4, 3, 2, 1, 1, 2, 3, 4, 5};
  const int max_row_count = seqNoLst.size();

  ui->BestBOExchange->setMinimumHeight(kRowHeight * (max_row_count + 1));

  DefaultTableModel* model = new DefaultTableModel(this);
  model->setTable(ui->BestBOExchange);
  ui->BestBOExchange->table()->setModel(model);

  model->setRowCount(max_row_count);
  model->setColumnCount(max_col_count);

  ui->BestBOExchange->setRealDataCount(max_row_count);

  STableColumnSet* tableSet =
      new STableColumnSet(ui->BestBOExchange, "ExchangeBest5Price", this);
  tableSet->setTableWidthFixed(false);

  BEGIN_COLUMN;
  ADD_COLUMN(0, tableSet, "", 0, 20, 12, -1, false, Qt::AlignCenter, kFixed,
             "");
  ADD_COLUMN(1, tableSet, "YTE", 0, -1, 12, 0.25, false,
             (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kAuto, "");
  ADD_COLUMN(2, tableSet, "YTM", 0, -1, 12, 0.25, false,
             (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kAuto, "");
  ADD_COLUMN(3, tableSet, "price", 0, -1, 12, 0.25, false,
             (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kAuto, "");
  ADD_COLUMN(4, tableSet, "Vol(万)", 0, -1, 12, 0.25, false,
             (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kAuto, "");

  tableSet->apply();

  ui->BestBOExchange->table()->horizontalHeader()->show();

  ExchangeSeqNoDelegate* seqNoDelegate =
      new ExchangeSeqNoDelegate(ui->BestBOExchange);
  ui->BestBOExchange->table()->setItemDelegateForColumn(0, seqNoDelegate);
  {
    QFont f = font();
    f.setBold(true);

    for (int row = 0; row < max_row_count; ++row) {
      for (int col = 0; col < max_col_count; ++col) {
        QStandardItem* item = new QStandardItem();
        model->setItem(row, col, item);
        item->setData((int)(Qt::AlignRight | Qt::AlignVCenter),
                      Qt::TextAlignmentRole);
        item->setData(StyleMgr::instance().color("Highlight"),
                      Qt::ForegroundRole);
        item->setData(StyleMgr::instance().color("BasicPlate"),
                      Qt::BackgroundRole);
        // item->setData(report.m_company_id, DataIdRole);
        item->setFont(f);
      }
      ui->BestBOExchange->table()->setRowHeight(row, kRowHeight);
    }

    for (int row = 0; row < max_row_count; ++row) {
      QStandardItem* item = model->item(row);
      item->setData(Qt::AlignCenter, Qt::TextAlignmentRole);
      item->setData(QString("%1").arg(seqNoLst[row]), Qt::DisplayRole);
      item->setData(QColor(Qt::white), Qt::ForegroundRole);
      item->setData((row < max_row_count / 2) ? QColor(21, 89, 142)
                                              : QColor(186, 106, 19),
                    PostfixTxtRectColor);
      item->setFont(f);
    }
  }
}

void BondDetailPage::onCurrentTabChanged(int id, bool b) {
  if (b) {
    const auto type = static_cast<BondDetailAllMarket::QuoteTypeId>(id);
    ui->btnShowDeals->setVisible(BondDetailAllMarket::Exchange == type);
    if (BondDetailAllMarket::Exchange == type) {
      on_btnShowDeals_toggled(ui->btnShowDeals->isChecked());
    } else {
      on_btnShowDeals_toggled(false);
    }

    const std::vector<bool>& markets = getMarketsForBond(m_data);
    ui->QuoteAndStream->setQuoteType(type, markets);
  }
}

void BondDetailPage::on_btnShowDeals_toggled(bool checked) {
  ui->btnShowDeals->setText(
      QString("%1成交信息").arg(checked ? "显示" : "隐藏"));
  ui->stackedWidget->setCurrentIndex(checked ? 0 : 1);
}

void BondDetailPage::onExchangeDataChanged(
    const QList<xQBExQuoteUnit_c>& datas) {
  QStandardItemModel* model =
      dynamic_cast<QStandardItemModel*>(ui->BestBOExchange->table()->model());
  if (!model) return;

  const CBondInfo& bi = m_data->bond();
  const bool bFull = CBondContainer::IsShowFullPrice(bi);
  const bool bRight = bi.IsRight();

  auto updateRow = [model, bFull, bRight](const xQBExQuoteUnit_c& data) {
    double fValue;
    QString szYTE, szYTM, szNet, szVol;  // szYTC, szYTP,

    for (int i = 0; i < 10; i++) {
      szYTE = szYTM = szNet = szVol = "--";
      const QBExQuote5& quote = data.m_Quote5[i];
      const char* yte = quote.m_YTE;
      const char* ytm = quote.m_YTM;
      const char* net = quote.m_NetPrice;
      const char* vol = quote.m_Vol;

      if (bRight && !bFull) {
        fValue = fabs(atof(yte));
        if (fValue > 0.0001) szYTE = SSTools::FormatePrice(yte);
      }

      if (!bFull) {
        fValue = fabs(atof(ytm));
        if (fValue > 0.0001) szYTM = SSTools::FormatePrice(ytm);
      }

      fValue = fabs(atof(net));
      if (fValue > 0.0001) szNet = SSTools::FormatePrice(net);

      if (vol[0] != '\0' && atof(vol) > 0.001)
        szVol = QString::number(atof(vol) / 10, 'f', 2);

      QStandardItem* item = nullptr;
      if ((item = model->item(i, 1))) {
        item->setData(szYTE, Qt::DisplayRole);
      }
      if ((item = model->item(i, 2))) {
        item->setData(szYTM, Qt::DisplayRole);
      }
      if ((item = model->item(i, 3))) {
        item->setData(szNet, Qt::DisplayRole);
      }
      if ((item = model->item(i, 4))) {
        item->setData(szVol, Qt::DisplayRole);
      }
    }
  };
  if (datas.empty()) return;
  const xQBExQuoteUnit_c& data = datas[datas.count() - 1];
  updateRow(data);
}
